import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken,getAdmin} from '@/utils/auth'

NProgress.configure({ showSpinner: false })// NProgress Configuration

function hasPermission(perms, route) {
    //如果没有声明meta或者meta.perm，都视为可以公共访问的路由
    if (!route.meta || !route.meta.perm) {
        return true;
    }
    if(perms.some(p=>p=="*")) {
        return true;
    }
    return perms.some(p=>p==route.meta.perm);
}
const loginRoute = "/login"
//不重定向白名单
// const whiteList = ['/login', '/auth-redirect','/error/401','/error/404']
const whiteList = new Set([loginRoute,'/authredirect'])

router.beforeEach((to, from, next) => {
    NProgress.start()
    let token = getToken();
    let hasToken = token != 'undefined' && token != undefined && token !=null && token != '';
    NProgress.start(); //窗口上方进度条
    if (hasToken) {
        //1.1先校验token是否存在，如果存在则登陆
        if (to.path === loginRoute) {
            next({ path: '/' });
            NProgress.done();
        } else {
            // 1.2 如果不是去登录页，判断是否有访问权限
            if(store.getters.visitor) {
                // 1.2.1 若该标记为true,是因为GetUserInfo返回结果发现用户信息中roles或perms为空数组，即未配置任何角色或权限，
                // 所以视为游客visitor给放行，放行后游客只能看到公共可以访问的菜单(即src/router/index.js中没有配置perm属性的路由)。
                next();
            }else if (!store.getters.perms || store.getters.perms.length === 0) {
                // 1.2.2 检查发现不是游客且未加载用户权限信息，应该调用接口加载用户权限信息
                // 用户刷新页面会导致vuex状态清空，或者用户首次登录，vuex中还没有权限信息。都要调用后台接口获得用户信息
                store.dispatch('GetUserInfo').then(res => {
                    let result = res.data;
                    // perm: [{name:'菜单1',val:'menu:1'}]，此处我只传了权限字符[*,a:add]
                    const perms = result.data.perms;
                    store.dispatch('GenerateRoutes', { perms }).then(() => { // 根据roles权限生成可访问的路由表
                        router.addRoutes(store.getters.addRouters); // 动态添加可访问路由表
                        next({ ...to, replace: true });// hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
                    });
                }).catch((err) => {
                    store.dispatch('FedLogOut').then(() => {
                        Message.error(err || '获取用户信息失败，请重试');
                        next({ path: '/' });
                    });
                });
            } else {
                // 1.2.3 如果vuex种有权限信息，匹配权限信息，匹配ok则放行
                if (hasPermission(store.getters.perms,to)) {
                    next();
                } else {
                    next({ path: '/401', replace: true, query: { noGoBack: true }});
                }
            }
        }
    } else {
        // 2.没有token
        // 如果要访问的路由在白名单中，直接进入；否则，重定向到登录页面
        whiteList.has(to.path) ? next() : next(loginRoute);
        NProgress.done();
    }
});

router.afterEach(() => {
    NProgress.done() // finish progress bar
});
